/*
 *所有关于tb_project_baseinfo类的业务代码应在此处编写
*可使用repository.调用常用方法，获取EF/Dapper等信息
*如果需要事务请使用repository.DbContextBeginTransaction
*也可使用DBServerProvider.手动获取数据库相关信息
*用户信息、权限、角色等使用UserContext.Current操作
*tb_project_baseinfoService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter
*/
using MYData.Entity.DomainModels;
using MYData.Core.Utilities;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using MYData.System.IRepositories;
using Mapster;
using System.Collections.Generic;
using System.Threading.Tasks;
using MYData.Core.Enums;
using System.Linq;
using MYData.Core.EFDbContext;
using MYData.Core.Utilities.Response;
using MYData.Core.ManageUser;
using System;
using MYData.Order.Services;
using System.Text.Json;
using NuGet.Protocol.Plugins;
using OfficeOpenXml.FormulaParsing.Excel.Operators;
using System.Diagnostics;
using MYData.Entity.DTO.ApiEntity.Input;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Database;
using Castle.DynamicProxy;
using System.IO;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using MYData.Core.Redis;
using MYData.Core.WorkFlow;
using MYData.Entity.DTO.ApiEntity.OutPut;
using System.Reflection;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace MYData.System.Services
{
    
    public partial class tb_project_baseinfoService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly Itb_project_baseinfoRepository _repository;//访问数据库
        private readonly Itb_project_workflowtableRepository _workRepository;
        //private readonly Itb_project_projectpersonnelRepository _projectpersonnel;
        private readonly VOLContext _db;

        [ActivatorUtilitiesConstructor]
        public tb_project_baseinfoService(
            Itb_project_baseinfoRepository dbRepository,
            IHttpContextAccessor httpContextAccessor
, Itb_project_workflowtableRepository workRepository,
        //Itb_project_projectpersonnelRepository projectpersonnel,
        VOLContext db)
        : base(dbRepository)
        {
            _httpContextAccessor = httpContextAccessor;
            _repository = dbRepository;
            _db = db;
            _workRepository = workRepository;
            //_projectpersonnel = projectpersonnel;
            //多租户会用到这init代码，其他情况可以不用
            //base.Init(dbRepository);
        }
        WebResponseContent webResponse = new WebResponseContent();
        //当前登录的信息
        UserInfo userInfo = UserContext.Current.UserInfo;
        /// <summary>
        /// 基本信息添加
        /// </summary>
        /// <param name="inputdto"></param>
        /// <returns></returns>
        public async Task<WebResponseContent> BaseInfoAdd(baseinfoInputDto inputdto)
        {

            // 将输入Dto转换为领域模型
            // 把输入DTO转换成tb_project_baseinfo实体
            var model = inputdto.Adapt<tb_project_baseinfo>();

            // 把输入DTO中的数据转换成tb_project_fundingsubject_realition_Dto实体列表 
            var model1 = inputdto.data.Adapt<List<tb_project_fundingsubject_realition_Dto>>();
            // 标记为非暂存
            model.isTs = false;
            // 开始数据库事务
            webResponse = _repository.DbContextBeginTransaction(() =>
            {
                // 添加基本信息到数据库
                _repository.Add(model);

                // 添加数据到关联表 
                tb_project_fundingsubject_realitionService.Instance.AddList(model1);
                //tb_project_expectedresultsService.Instance.AddList(modelone);
                //tb_project_participationerService.Instance.AddList(modeltwo);
                //tb_project_planontargetService.Instance.AddList(modelthree);

                // 保存更改并返回成功响应
                // 设置响应类型为保存成功，并保存数据库
                webResponse.OK(ResponseType.SaveSuccess.ToString(), _repository.SaveChangesAsync());

                // 如果有附加操作，则执行并返回响应
                // 如果存在AddOnExecuted，则执行
                if (base.AddOnExecuted != null)
                {
                    webResponse = base.AddOnExecuted(model, null);
                }
                // 返回响应
                return webResponse;
            });
            // 返回响应
            return webResponse;
        }

        /// <summary>
        /// 基本信息修改
        /// </summary>
        /// <param name="inputdto"></param>
        /// <returns></returns>
        public async Task<WebResponseContent> BaseInfoUpt(baseinfoUpdateDto updatedto)
        {
            // 将输入Dto转换为领域模型
            // 把输入DTO转换成tb_project_baseinfo实体
            var model = updatedto.Adapt<tb_project_baseinfo>();
            // 把输入DTO中的数据转换成tb_project_fundingsubject_realition_Dto实体列表 
            var model1 = updatedto.data.Adapt<List<tb_project_fundingsubject_realition_Dtotwo>>();
            //var modelone = inputdto.dataone.Adapt<List<tb_project_expectedresults_Dto>>();
            //var modeltwo = inputdto.datatwo.Adapt<List<tb_project_participationer_Dto>>();
            //var modelthree = inputdto.datathree.Adapt<List<tb_project_planontarget_Dto>>();
            // 标记为非暂存
            //model.isTs = false;

            // 开始数据库事务
            webResponse = _repository.DbContextBeginTransaction(() =>
            {
                // 添加基本信息到数据库
                _repository.Update(model);
                // 添加数据到关联表 
                tb_project_fundingsubject_realitionService.Instance.UptList(model1);
                //tb_project_expectedresultsService.Instance.AddList(modelone);
                //tb_project_participationerService.Instance.AddList(modeltwo);
                //tb_project_planontargetService.Instance.AddList(modelthree);

                // 保存更改并返回成功响应
                // 设置响应类型为保存成功，并保存数据库
                webResponse.OK(ResponseType.SaveSuccess.ToString(), _repository.SaveChangesAsync());

                // 如果有附加操作，则执行并返回响应
                // 如果存在AddOnExecuted，则执行
                //if (base.AddOnExecuted != null)
                //{
                //    webResponse = base.AddOnExecuted(model, null);
                //}
                // 返回响应
                return webResponse;
            });
            // 返回响应
            return webResponse;
        }


        /// <summary>
        /// 暂存添加
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        public WebResponseContent ProductInfoAddTsAsync(ProjectInfoTsInput_Dto inputDto)
        {
            // 定义雪花id
            string id = Ids.NextIdString();

            //Dto转换
            var model = inputDto.Adapt<tb_project_baseinfo>();
            var model2 = inputDto.data.Adapt<IEnumerable<ProjectFundingItemInput_Dto>>();
            var modelone = inputDto.dataone.Adapt<IEnumerable<tb_project_expectedresults_Dto>>();
            var modeltwo = inputDto.datatwo.Adapt<IEnumerable<tb_project_participationer_Dto>>();
            var modelthree = inputDto.datathree.Adapt<IEnumerable<tb_project_planontarget_Dto>>();
            var fileModel = inputDto.File.Adapt<IEnumerable<FileUploadInput_Dto>>();
            //为model的主键赋值
            model.projectId = id;

            model.isTs = false;
            //流程关系表添加
            tb_project_workflowtable workflowtable = new tb_project_workflowtable();
            var workFlow = _db.Set<Sys_WorkFlow>().Where(s => s.WorkTable == "tb_project_baseinfo").FirstOrDefault();
            workflowtable.id = Ids.NextIdString();
            workflowtable.workFlowId = workFlow.WorkFlow_Id;
            workflowtable.workName = workFlow.WorkName;
            workflowtable.projectTableKey = id;
            workflowtable.projectTable = workFlow.WorkTable;
            workflowtable.workTableName = workFlow.WorkTableName;
            workflowtable.currentOrderId = "1";
            workflowtable.auditStatus = 0;//0是审核中
            workflowtable.createDate = DateTime.Now;
            workflowtable.creator = userInfo.UserName;
            // 在事务中执行添加操作
            webResponse = _repository.DbContextBeginTransaction(() =>
            {
                //基础信息添加
                _repository.Add(model, false);
                //流程关系表添加
                _workRepository.Add(workflowtable, false);
                //科目预算添加
                tb_project_fundingsubject_realitionService.Instance.AddListTs(model2, model.projectId);
                //文件上传
                tb_project_appendixService.Instance.AddFileListTs(fileModel, model.projectId);
                //项目预期成果表添加
                tb_project_expectedresultsService.Instance.AddList(modelone, model.projectId);
                //项目参与人信息表添加
                tb_project_participationerService.Instance.AddList(modeltwo, model.projectId);
                //计划与目标添加
                tb_project_planontargetService.Instance.AddList(modelthree, model.projectId);

                // 保存更改并返回成功响应
                webResponse.OK(ResponseType.SaveSuccess.ToString(), _repository.SaveChanges());

                // 如果有附加操作，则执行并返回响应
                if (base.AddOnExecuted != null)
                {
                    webResponse = base.AddOnExecuted(model, null);
                }
                return webResponse;
            });
            // 返回响应
            return webResponse;
        }


        /// <summary>
        /// 暂存修改
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        public WebResponseContent ProductInfoUptTsAsync(ProjectInfoTsUpt_Dto UpdateDto)
        {

            //Dto转换
            //项目基础信息表
            var Uptmodel = UpdateDto.Adapt<tb_project_baseinfo>();
            //项目立项经费表
            var Uptmodel2 = UpdateDto.data.Adapt<IEnumerable<ProjectFundingItemUpdate_Dto>>();
            //项目预期成果表
            var Uptmodelone = UpdateDto.dataone.Adapt<IEnumerable<tb_project_expectedresultsUpdate_Dto>>();
            //项目参与人信息表
            var Uptmodeltwo = UpdateDto.datatwo.Adapt<IEnumerable<tb_project_participationerUpdate_Dto>>();
            //计划于目标表
            var Uptmodelthree = UpdateDto.datathree.Adapt<IEnumerable<tb_project_planontargetUpdate_Dto>>();

            //流程关系表修改
            //找到立项基本信息的流程
            var workFlow = _db.Set<tb_project_workflowtable>().Where(s => s.projectTableKey == Uptmodel.projectId).FirstOrDefault();
            workFlow.auditStatus = 0;
            // 在事务中执行添加操作
            webResponse = _repository.DbContextBeginTransaction(() =>
            {
                //基础信息修改
                _repository.Update(Uptmodel, false);
                //流程关系表修改
                _workRepository.Update(workFlow, false);
                //科目预算修改
                tb_project_fundingsubject_realitionService.Instance.UptListTs(Uptmodel2, Uptmodel.projectId);
                //项目预期成果表修改
                tb_project_expectedresultsService.Instance.UptList(Uptmodelone, Uptmodel.projectId);
                //项目参与人信息表修改
                tb_project_participationerService.Instance.UptList(Uptmodeltwo, Uptmodel.projectId);
                //计划与目标修改
                tb_project_planontargetService.Instance.UptList(Uptmodelthree, Uptmodel.projectId);

                // 保存更改并返回成功响应
                webResponse.OK(ResponseType.SaveSuccess.ToString(), _repository.SaveChanges());

                // 如果有附加操作，则执行并返回响应
                if (base.AddOnExecuted != null)
                {
                    webResponse = base.AddOnExecuted(Uptmodel, null);
                }
                return webResponse;
            });
            // 返回响应
            return webResponse;
        }



        //立项基本信息主键查找
        public async Task<WebResponseContent> BaseinfoSearch(string projectId)
        {
            var Current = typeof(tb_project_baseinfo);
          
            var value = Current.GetField("projectId");
            var methondName = Current.GetMethod("");
            //var parentId = "0";
            //var tbBaseInfo = (await _repository.FindAsync(x => x.projectId == projectId)).ToList();
            //查找项目详细信息
            var list = from x in _db.Set<tb_project_baseinfo>().ToList()
                       join y in _db.Set<tb_project_sourceinfo>().ToList() on x.projectType equals y.Id
                       join z in _db.Set<tb_project_sourceinfo>().ToList() on x.projectLevel equals z.Id
                       where x.projectId == projectId
                       select new
                       {
                           x.projectId,
                           x.projectName,
                           x.projectNumber,
                           x.projectDepartresult,
                           x.projectDepartperson,
                           x.secretaryPhone,
                           x.projectYear,
                           x.projectWriteperson,
                           x.specialMoney,
                           x.projectSubject,
                           x.projectEndtime,
                           projectType = y.dicValue,
                           x.projectScoreunit,
                           x.projectUndertakeunit,
                           x.projectEntrust,
                           x.projectRemark,
                           x.touchPerson,
                           x.personRemark,
                           x.projectPerson,
                           x.projectSecretary,
                           x.projectPersontype,
                           x.projectWritetime,
                           x.projectMoney,
                           x.supportMoney,
                           x.projectStarttime,
                           x.projectStudytype,
                           projectLevel = z.dicValue,
                           x.projectKind,
                           templateId = GetTemplateId(x.projectId),
                           plateItem = GetPlateItem(x.projectId),
                           funsRatioName = GetFunsRatioName(x.projectId),
                           appendix = GetAppendix(x.projectId)
                       };
            return webResponse.OK("success", list);
        }

        public async Task<WebResponseContent> ProjectApprovalInformation(string projectId)
        {
            var planontarget = _db.Set<tb_project_planontarget>().Where(x => x.projectId == projectId).ToList();
            var expectedresults = _db.Set<tb_project_expectedresults>().Where(x => x.projectId == projectId).ToList();
            var baseinfo = _db.Set<tb_project_baseinfo>().Where(x => x.projectId == projectId).ToList();
            var projectpersonnel = _db.Set<tb_project_participationer>().Where(x => x.projectId == projectId).ToList();
            //var realition = from x in _db.Set<tb_project_fundingsubject_realition>().Where(x => x.projectId == projectId) join y in _db.Set<tb_project_fundtemplate>
            //var appendix = _db.Set<tb_project_appendix>().Where(x=>x.projectID== projectId).ToList();
            var list = new
            {
                planontarget,
                expectedresults,
                baseinfo,
                projectpersonnel,
                appendix = GetAppendix(projectId),
                platelist = GetItem(projectId)
            };
            return webResponse.OK("success", list);
        }
        private dynamic GetAppendix(string projectId)
        {
            var list = from y in _db.Set<tb_project_appendix>()
                       where y.projectID == projectId
                       select new
                       {
                           y.appendixUrl,
                           y.appendixName
                       };
            return list;
        }
        //获取指定项目的经费信息
        private dynamic GetPlateItem(string projectId)
        {
            var platelist = from x in _db.Set<tb_project_fundingsubject_realition>()
                            join y in _db.Set<Tb_Project_Fundtemplate_Item>() on x.subjectId equals y.budgetItemId
                            where x.projectId == projectId
                            select new
                            {
                                budgetType = (bool)y.budgetType ? "直接费用" : "间接费用",
                                x.directFunding,
                                x.overheadFunding,
                                y.budgetitemName
                            };
            return platelist;
        }
        /// <summary>
        /// 判断经费科目是否最后一级
        /// </summary>
        /// <param name="budgetItemId">当前的科目id</param>
        /// <param name="templateId">模板id</param>
        /// <param name="budgetType">直接费用或间接费用</param>
        /// <returns></returns>
        private bool GetTemplateBool(string budgetItemId, string templateId, bool budgetType)
        {
            //查找指定模板关系表
            var lists = _db.Set<Tb_Project_Templatesubject_Relationship>().Where(s => s.fundtemplateId == templateId && s.supportingBudgetTypeId == budgetType).FirstOrDefault();
            //科目数组
            string[] ids = lists.supportingBudgetId.Split(',');
            //查找当前科目下的子数据 并且子数据存在关系表
            var list = _db.Set<Tb_Project_Fundtemplate_Item>().Where(s => s.partentId == budgetItemId && ids.Contains(s.budgetItemId));
            return list.Count() != 0;
        }
        //获取指定项目的经费预算科目
        private dynamic GetItem(string projectId)
        {
            //var platelistT = _db.Set<Tb_Project_Fundtemplate_Item>().Where(x => x.budgetType == true).ToList();
            //var list11 = _db.Set<tb_project_fundingsubject_realition>().Where(x => x.projectId == projectId).ToList();
            var platelistT = from x in _db.Set<tb_project_fundingsubject_realition>().Where(x => x.projectId == projectId).ToList()
                             join y in _db.Set<Tb_Project_Fundtemplate_Item>().Where(x => x.budgetType == true).ToList() on x.subjectId equals y.budgetItemId
                             where x.projectId == projectId
                             select new
                             {
                                 budgetType = "直接费用",
                                 x.directFunding,
                                 x.overheadFunding,
                                 y.budgetitemName,
                                 x.templateId,
                                 x.subjectId,
                                 projectId,
                                 IsChilent = GetTemplateBool(y.budgetItemId, x.templateId, true)
                             };
            var platelistF = from x in _db.Set<tb_project_fundingsubject_realition>().ToList()
                             join y in _db.Set<Tb_Project_Fundtemplate_Item>().Where(x => x.budgetType == false).ToList() on x.subjectId equals y.budgetItemId
                             join z in _db.Set<Tb_Project_Templatesubject_Relationship>().Where(s => s.supportingBudgetTypeId == false).ToList() on x.templateId equals z.fundtemplateId
                             where x.projectId == projectId
                             select new
                             {
                                 budgetType = "间接费用",
                                 x.directFunding,
                                 x.overheadFunding,
                                 y.budgetitemName,
                                 x.templateId,
                                 x.subjectId,
                                 projectId,
                                 IsChilent = GetTemplateBool(y.budgetItemId, x.templateId, false)
                             };
            var list = new
            {
                platelistT,
                platelistF
            };
            return list;
        }

        //查找指定项目的经费模板
        private string GetTemplateId(string projectId)
        {
            var obj = _db.Set<tb_project_fundingsubject_realition>().Where(s => s.projectId == projectId).FirstOrDefault();
            var Template = _db.Set<Tb_Project_Fundtemplate>().Where(s => s.fundtemplateId == obj.templateId).FirstOrDefault();
            return Template.fundtemplateName??"";
        }
        //查找经费模板转率名称
        private string GetFunsRatioName(string projectId)
        {
            var obj = _db.Set<tb_project_fundingsubject_realition>().Where(s => s.projectId == projectId).FirstOrDefault();
            var Template = _db.Set<Tb_Project_Fundtemplate>().Where(s => s.fundtemplateId == obj.templateId).FirstOrDefault();
            return Template.fundtemplateFunsRatioName;
        }
            /// <summary>
            /// 获取项目立项信息列表
            /// </summary>
            /// <returns></returns>
            public async Task<WebResponseContent> GetProjectListAsync(string projectName, int size, int index)
        {
            var db = _db;
            //获取信息
            var list = from x in _db.Set<tb_project_baseinfo>().ToList()
                           //join y in _db.Set<tb_project_sourceinfo>().ToList() on x.projectId equals y.productId
                       join z in _db.Set<tb_project_sourceinfo>().ToList() on x.projectLevel equals z.Id
                       where x.projectName.Contains(projectName ?? "") && x.IsDel==0
                       select new
                       {
                           x.projectId,
                           x.projectNumber,
                           x.projectName,
                           x.projectStarttime,
                           x.projectPerson,
                           x.specialMoney,
                           x.supportMoney,
                           projectLevel = z.dicValue,
                           x.projectUndertakeunit,
                           progress = tb_project_workflowstepService.Instance.GetProgress(x.projectId, "tb_project_baseinfo"),
                           operate = tb_project_workflowstepService.Instance.GetOperate(x.projectId, "tb_project_baseinfo"),
                           //currentOrderId = GetCurrentOrder(x.projectId)
                           //y.orgName
                       };

            list = list.Skip((index - 1) * size).Take(size);
            return webResponse.OK("获取信息成功", list);
            //return webResponse;
        }
        //获取流程节点序号
        //private int GetCurrentOrder(string projectId)
        //{
        //    var pro = _db.Set<tb_project_workflowtable>().Where(s => s.projectTableKey == projectId).FirstOrDefault();
        //    return pro == null ? 0 : pro.currentOrderId;
        //}
       

        /// <summary>
        /// 项目名称唯一判断
        /// </summary>
        /// <param name="projectName"></param>
        /// <returns></returns>
        public async Task<WebResponseContent> ProjectNameSole(string projectName)
        {
            List<tb_project_baseinfo> list = await _repository.FindAsync(x => x.projectName.Equals(projectName));
            bool result = true;
            if (list.Count() > 0)
                result = false;
            return webResponse.OK("项目名称查重", result);
        }
        /// <summary>
        /// 项目编号唯一判断
        /// </summary>
        /// <param name="projectName"></param>
        /// <returns></returns>
        public async Task<WebResponseContent> ProjectNumSole(string projectNum)
        {
            List<tb_project_baseinfo> list = await _repository.FindAsync(x => x.projectNumber.Equals(projectNum));
            bool result = true;
            if (list.Count() > 0)
                result = false;
            return webResponse.OK("项目编号查重", result);
        }
        /// <summary>
        /// 立项基本信息删除（软）
        /// </summary>
        /// <param name="projectid"></param>
        /// <returns></returns>
        public async Task<WebResponseContent> DelProject(string projectid)
        {
            var ids = projectid.Split(',');
            foreach (var item in ids)
            {
                var list = _db.Set<tb_project_baseinfo>().Find(item);
                list.IsDel = 1;
                _db.Update(list);
            }
            if (_db.SaveChanges()>0)
            {
                return webResponse.OK("删除成功");
            }
            else
            {
                return webResponse.OK("删除失败");
            }
        }

        /// <summary>
        /// 暂存信息添加到Redis
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        //public WebResponseContent InsertBaseInfoTsByRedis(InsertBaseInfoByRedis_Dto inputDto)
        //{
        //    //拿到用户数据
        //    string res = RedisHelper.Get(string.Format(RedisKeyConfig.ProjectUserInfoKey, inputDto.UserId));
        //    //获取用户的暂存信息key
        //    string BaseInfoTsKey = string.Format(RedisKeyConfig.BaseInfoKey, inputDto.UserId);
        //    if(res!=null)//确认用户登录
        //    {
        //        //确认暂存数据
        //        string BaseInfoTsData = RedisHelper.Get(BaseInfoTsKey);
        //        if(BaseInfoTsData!=null)
        //        {
        //            RedisHelper.Set(BaseInfoTsKey, inputDto.InputData);//没有数据就直接将本次添加的数据添加到用户的暂存信息中
        //        }
        //        else
        //        {
        //            ProjectInfoTsInput_Dto resData = Newtonsoft.Json.JsonConvert.DeserializeObject<ProjectInfoTsInput_Dto>(BaseInfoTsData);

        //            Project
        //        }
        //    }
        //}
    }
}
